<route lang="json5">
{
  meta: {
    auth: true,
    label: '撒花',
  },
}
</route>

<template>
  <div class="overflow-y-scroll relative">
    <a-form ref="formRef" :model="config" :style="{ width: '600px' }" @submit="handleScatterFlowers">
      <a-form-item field="particleCount" label="数量">
        <a-input-number v-model="config.particleCount" :style="{ width: '6rem' }" :min="0" :step="10" />
      </a-form-item>
      <!-- 环形选择(x)展示(√)器... -->
      <a-progress
        class="!absolute left-96 top-16"
        type="circle"
        :style="{
          transform: `rotate(${90 - config.angle + config.spread / 2}deg) rotateY(180deg)`,
        }"
        status="warning"
        :show-text="false"
        :percent="config.spread / 360"
      />
      <a-form-item field="angle" label="发射角度">
        <a-slider v-model="config.angle" :style="{ width: '15rem' }" show-ticks :max="360" />
      </a-form-item>
      <a-form-item field="spread" label="扩散角度">
        <a-slider v-model="config.spread" :style="{ width: '15rem' }" show-ticks :max="360" />
      </a-form-item>

      <a-form-item field="startVelocity" label="移动速度(px)">
        <a-input-number v-model="config.startVelocity" :style="{ width: '6rem' }" :min="0" :step="10" />
      </a-form-item>
      <a-form-item field="decay" label="初速度">
        <a-slider v-model="config.decay" :style="{ width: '15rem' }" show-ticks :step="0.05" :max="1" />
      </a-form-item>
      <a-form-item field="gravity" label="重力">
        <a-slider v-model="config.gravity" :style="{ width: '15rem' }" show-ticks :step="0.05" :max="1" />
      </a-form-item>
      <a-form-item field="drift" label="不要管这个">
        <a-input-number v-model="config.drift" :style="{ width: '6rem' }" :min="0" :step="10" />
      </a-form-item>
      <a-form-item field="ticks" label="移动次数">
        <a-input-number v-model="config.ticks" :style="{ width: '6rem' }" :min="0" :step="10" />
      </a-form-item>
      <a-form-item field="origin" label="位置" content-class="flex gap-2">
        <span>(</span>
        <a-input-number v-model="config.origin.x" :style="{ width: '6rem' }" :min="0" :max="1" :step="0.1" />
        <span>,</span>
        <a-input-number v-model="config.origin.y" :style="{ width: '6rem' }" :min="0" :max="1" :step="0.1" />
        <span>)</span>
      </a-form-item>
      <a-form-item field="colors" label="颜色">
        <a-select :style="{ width: '15rem' }" v-model="config.colors" multiple allow-create></a-select>
      </a-form-item>
      <a-form-item field="shapes" label="形状" content-class="flex-col !items-start gap-1">
        <div class="flex gap-1">
          <a-button @click="config.shapes.push('circle')">
            <template #icon>
              <Icon icon="bx:plus" />
            </template>
          </a-button>
          <a-button @click="config.shapes = config.shapes.sort((a, b) => a.localeCompare(b))">
            <template #icon>
              <Icon icon="bx:sort" />
            </template>
          </a-button>
        </div>
        <div class="flex flex-wrap gap-1">
          <a-tag
            size="large"
            closable
            @click="config.shapes.splice(i, 1, item === 'circle' ? 'square' : 'circle')"
            @close="config.shapes.splice(i, 1)"
            class="cursor-pointer select-none"
            v-for="(item, i) in config.shapes"
          >
            <span class="mr-2">{{ item == 'circle' ? 'O' : '口' }}</span>
          </a-tag>
        </div>
      </a-form-item>

      <a-form-item field="scalar" label="缩放">
        <a-input-number v-model="config.scalar" :style="{ width: '6rem' }" :min="0" :step="0.1" />
      </a-form-item>
      <a-form-item field="zIndex" label="层级">
        <a-input-number v-model="config.zIndex" :style="{ width: '6rem' }" :min="0" :step="10" />
      </a-form-item>
      <a-form-item field="disableForReducedMotion" label="不知道是啥">
        <a-switch v-model="config.disableForReducedMotion" />
      </a-form-item>
      <a-form-item>
        <a-button
          v-copy="{
            text: JSON.stringify(config),
          }"
          class="mr-2"
        >
          复制参数
        </a-button>
        <a-button html-type="submit">发射</a-button>
      </a-form-item>
    </a-form>
  </div>
</template>

<script lang="ts" setup>
import confetti from 'canvas-confetti'
import { debounce, cloneDeep } from 'lodash-es'

const DEFAULT_CONFIG = {
  particleCount: 50, // 要发射的五彩纸屑数量
  angle: 90, // 发射角度 向右为0
  spread: 45, // 散射角度
  startVelocity: 45, // 移动速度
  decay: 0.9, // 速度递减 0-1
  gravity: 1, // 重力  1:全重力 0:无重力
  drift: 0, // 五彩纸屑将漂移到一侧的程度。默认值为 0，表示它们将直接下降。左边使用负数，右边使用正数。
  flat: false, // Boolean（默认值：false）：可以选择关闭三维五彩纸屑在现实世界中的倾斜和摆动。是的，他们看起来有点难过，但你们都要求他们，所以不要怪我。
  ticks: 200, // 数字（默认值：200）：五彩纸屑移动的次数。
  origin: {
    x: 0.5, // 页面上的位置，分别为左边缘和右边缘。 点击位置： e.clientX / innerWidth,
    y: 0.5, // 页面上的位置，分别是上边缘和下边缘。 点击位置： e.clientY / innerHeight
  },
  colors: ['#bb0000', '#00bbff'], //颜色
  shapes: ['circle'], //square 和 circle
  scalar: 1, // 缩放
  zIndex: 100, // 层级
  disableForReducedMotion: false, // 禁用
}

type IConfig = Omit<typeof DEFAULT_CONFIG, 'shapes'> & {
  shapes: ('circle' | 'square')[]
}

const config = reactive<IConfig>(DEFAULT_CONFIG as any)

function handleScatterFlowers({ errors }: any) {
  if (errors) return
  console.log(cloneDeep(config))
  confetti(cloneDeep(config))
}

const _handleScatterFlowers = debounce(() => {
  handleScatterFlowers({})
}, 500)

watch(config, _handleScatterFlowers, { deep: true })
</script>
